/**
 * Projet de LIF12 : messagerie instantanée.
 * Sockets
 *
 * @file sockets/sockets.c
 * @author Elsa FLECHON elsa.flechon@etu.univ-lyon1.fr
 * @author Emmanuel GAUDE emmanuel.gaude@etu.univ-lyon1.fr
 * @author Grégoire LEMASSON gregoire.lemasson@etu.univ-lyon1.fr
 * @since 2009/03/10
 * @version 2009/03/11
 */

/* -- Inclusion de l'en-tête. ----------------------------------------------- */
#include "sockets.h"

void sockets_init() {
	#if defined (WIN32)
  WSADATA WSAData;
  int err = WSAStartup(MAKEWORD(2,0), &WSAData);
  if(err) {
    perror("Probleme avec l'initialisation des sockets WIN32 ");
    exit(EXIT_FAILURE);
  }
	#endif
	return;
}

int
main (int argc, char *argv[])
{
	struct hostent *hp; // Pour obtenir l'adresse du serveur à partir de son nom

    // ######################################################
    // (1) Creation du socket (1)
    // Tout d'abord, il faut créer un socket,
    // ######################################################
  s = socket(AF_INET, SOCK_STREAM, 0); // AF_INET pour IPv4
                                       // SOCK_STREAM signifie TCP,
                                       // 0 il n'y a pas de protocole à choisir
  if (s == INVALID_SOCKET)
    {
      perror("Erreur à la creation du socket");
      exit(1);
    }


  // ######################################################
  // (3) Préparation de la connexion
  // ensuite il faut retrouver l'adresse IP de l'hôte (ordinateur) hébergeant
  // le serveur à l'aide de la fonction gethostbyname()
  // ######################################################
  hp = gethostbyname(NOM_SERVEUR); // Pour le test c'est "localhost"

  // Definition de l'adresse du serveur
  sin.sin_family = AF_INET;
  sin.sin_port = htons(PORT_SERVEUR); // htons sert à transformer l'entier en entier 16bits
  memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); // On copie le résultat de gethostbyname
                                                   // au bon endroit
  // Si on connait l'addresse IP On peut aussi utiliser
  // sin.sin_addr.s_addr = inet_addr("127.0.0.1");

  // ######################################################
  // (4) Demande de connexion
  //  enfin, établir la connexion par la fonction connect()
  // ######################################################

  if(connect(s, (SOCKADDR *)&sin, sizeof(sin)) <0)
    {
      perror("connect");
      exit(1);
    }
  printf("Connection à %s sur le port %d\n", inet_ntoa (sin.sin_addr), htons(sin.sin_port));
  printf("envoie de données sur le socket %d\n ",s);


  // ######################################################
  // (5) Dialogue
  // Une fois la connexion établie, le serveur et le client peuvent s'échanger des messages
  // envoyés par write() ou send() et lus par read()ou recv() selon un protocole établi.
  // Ici nous utiliseront le protocole suivant : le client écrit et le serveur lit.
  // ######################################################
  while (1) {
    char buff[TAILLE_BUFF];
    fgets(buff, TAILLE_BUFF, stdin);
    // Le dernier carractère est un retour chariot
    buff[strlen(buff)-1] = '\0';

    if (strcmp(buff, "fin")==0) {
	// Quand l'utilisateur tape fin on sort
	break;
      }
    sock_err = send(s, (char*)buff, (strlen(buff)+1)*sizeof(char), MSG_NOSIGNAL);
    // s le socket sur laquel on ecrit
    // buff le message écrit
    // (strlen(buff)+1)*sizeof(char) la longueur du mesage
    // MSG_NOSIGNAL lorsque la connexion est brisée, send renvoie une erreur et
    //              ne génère pas de signaux (que je n'ai pas envie de traiter)
    if (sock_err < 0) {
      perror("erreur dans le send");
      break;
    }
  }


  // ######################################################
  // (6) Fermeture de la connexion
  // ######################################################
  if (close(s)< 0) {
    perror("Problème à la fermeture du socket");
  }
#if defined (WIN32)
  // Ceci est du code spécifique à windows
  WSACleanup();
#endif

  fprintf(stdout, "bye\n");
  return 0;
}


